package pri.zxx.webdemo.aop.redisLock;

import org.springframework.context.event.EventListener;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.core.RedisKeyExpiredEvent;

import java.util.Arrays;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;

/**
 * 监听key过期时间，判断是否有加锁过期了，不用循环setnx
 *
 * @author wangn <15124178@qq.com> 2020/10/13
 */
public class RedisListener {
    private static final ConcurrentHashMap<String, CountDownLatch> COUNT_DOWN_MAP = new ConcurrentHashMap<>();

    /**
     * 将线程与key进行关联，并添加到容器中
     * Associate the countDownLatch with the lock-key and add it to the container
     *
     * @param lockKey        redis的锁钥匙 redis lock key
     * @param countDownLatch 多线程计数器
     */
    public static void addCountDownLatch(String lockKey, CountDownLatch countDownLatch) {
        COUNT_DOWN_MAP.put(lockKey, countDownLatch);
    }

    /**
     * Handle redis key events
     *
     * @see MessageListener
     */
    @EventListener
    public void onMessage(RedisKeyExpiredEvent event) {
        if (!LockRedisAop.PREFIX.equals(event.getKeyspace())) {
            return;
        }
        String key = event.getKeyspace() + Arrays.toString(event.getId());
        if (COUNT_DOWN_MAP.containsKey(key)) {
            CountDownLatch countDownLatch = COUNT_DOWN_MAP.get(key);
            countDownLatch.countDown();
            COUNT_DOWN_MAP.remove(key);
        }
    }
}
